home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 November: Tool Chest / Dev.CD Nov 96 TC / Dev.CD Nov 96 TC.toast / Sample Code / Interapplication Communication / MenuScripter 4.0 / Sources / MSAECountElements.c < prev    next >
Encoding:
Text File  |  1996-07-09  |  5.9 KB  |  228 lines  |  [TEXT/CWIE]

  1. // MSAECountElements.c
  2. //
  3. // Original version by Jon Lansdell and Nigel Humphreys.
  4. // 4.0 and 3.1 updates by Greg Sutton.
  5. // ©Apple Computer Inc 1996, all rights reserved.
  6.  
  7. /*
  8.     Changes for 3.1
  9.  
  10.     14-Nov-95 : GS : Disposed of all interim descriptors in DoCountElements()
  11.                         and GetDescForNumberOfElements().
  12.  
  13.     Changes for 4.0
  14.  
  15.     29-Feb-96 : GS : Added ability to count menus and menu items in MyCountProc()
  16. */
  17.  
  18. #include "MSAECountElements.h"
  19.  
  20. #include "MSToken.h"
  21. #include "MSAEUtils.h"
  22. #include "MSAETextUtils.h"
  23. #include "MSAEWindowUtils.h"
  24. #include "MSAEMenuUtils.h"
  25.  
  26.  
  27. #pragma segment AppleEvent
  28.  
  29.  
  30. // -----------------------------------------------------------------------
  31. //    Name:       DoCountElements
  32. //    Purpose:    Handles the Number Of Elements AppleEvent.
  33. // -----------------------------------------------------------------------
  34.  
  35. pascal OSErr    DoCountElements(const AppleEvent    *theAppleEvent,
  36.                                       AppleEvent    *reply,
  37.                                       long            handlerRefCon)
  38. {
  39. #ifdef __MWERKS__
  40.     #pragma unused (handlerRefCon)
  41. #endif
  42.  
  43.     AEDesc       container = {typeNull, NULL},
  44.                 countDesc = {typeNull, NULL};
  45.     DescType     desiredType;
  46.     DescType     returnedType;
  47.     Size         actualSize;
  48.       OSErr        err;
  49.     
  50.         // pick up direct object, which is the container
  51.         // in which things are to be counted.
  52.     err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &container);
  53.     if (noErr != err) goto done;
  54.         
  55.         // now the class of objects to be counted
  56.     err = AEGetParamPtr(theAppleEvent, keyAEObjectClass, typeType,
  57.                                 &returnedType, (Ptr)&desiredType, sizeof(desiredType), &actualSize);
  58.     if (noErr != err) goto done;
  59.         
  60.         // missing any parameters?
  61.     err = GotRequiredParams(theAppleEvent);
  62.     if (noErr != err) goto done;
  63.     
  64.         // now get descriptor for count - put through function that
  65.         // can handle lists.
  66.     err = GetDescForNumberOfElements(desiredType, &container, &countDesc);
  67.     
  68.     err = AddResultToReply(&countDesc, reply, err);
  69.  
  70. done:
  71.     if (container.dataHandle)
  72.         AEDisposeDesc(&container);
  73.     if (countDesc.dataHandle)
  74.         AEDisposeDesc(&countDesc);
  75.     
  76.     return(err);
  77. } // DoCountElements
  78.  
  79.  
  80. OSErr    GetDescForNumberOfElements(DescType desiredType, AEDesc* container, AEDesc* result)
  81. {
  82.     long        itemCount,
  83.                 index,
  84.                 elementCount;
  85.     AEDesc        tempDesc = {typeNull, NULL},
  86.                 aDesc = {typeNull, NULL},
  87.                 resultDesc = {typeNull, NULL};
  88.     DescType    returnedType;
  89.     OSErr        err;
  90.     
  91.             // If it's an object specifier, resolve into a token
  92.     if (typeObjectSpecifier == container->descriptorType)
  93.         err = AEResolve(container, kAEIDoMinimum, &tempDesc);
  94.     else    // Otherwise, just copy it
  95.         err = AEDuplicateDesc(container, &tempDesc);
  96.  
  97.     if (noErr != err) goto done;
  98.  
  99.     if (typeAEList == tempDesc.descriptorType)
  100.     {
  101.         err = AECreateList(NULL, 0 , false, result);    // Result will also be a list of items
  102.         if (noErr != err) goto done;
  103.         err = AECountItems(&tempDesc, &itemCount);
  104.         if (noErr != err) goto done;
  105.  
  106.         for (index = 1; index <= itemCount; index++)    // Do in forward order
  107.         {
  108.             err = AEGetNthDesc(&tempDesc, index, typeWildCard, &returnedType, &aDesc);
  109.  
  110.             if (noErr == err)        // Call this function recursively if necessary
  111.                 err = GetDescForNumberOfElements(desiredType, &aDesc, &resultDesc);
  112.             
  113.             if (noErr == err)        // Add item to the end of our list
  114.                 err = AEPutDesc(result, 0, &resultDesc);
  115.             
  116.             if (aDesc.dataHandle)
  117.                 AEDisposeDesc(&aDesc);
  118.             if (resultDesc.dataHandle)
  119.                 AEDisposeDesc(&resultDesc);
  120.         }
  121.     }
  122.     else
  123.     {
  124.         err = MyCountProc(desiredType, tempDesc.descriptorType, &tempDesc, &elementCount);
  125.         if (noErr != err) goto done;
  126.         err = AECreateDesc(typeLongInteger, (Ptr)&elementCount, sizeof(elementCount), result);
  127.     }
  128.  
  129. done:
  130.     if (tempDesc.dataHandle)
  131.         AEDisposeDesc(&tempDesc);
  132.     if (aDesc.dataHandle)
  133.         AEDisposeDesc(&aDesc);
  134.     if (resultDesc.dataHandle)
  135.         AEDisposeDesc(&resultDesc);
  136.  
  137.     return(err);
  138. }
  139.  
  140.  
  141. // This count procedure is installed along with MyCompareProc() to support
  142. // formTest and formWhose.
  143.  
  144. pascal OSErr MyCountProc(DescType desiredType, DescType containerClass,
  145.                                         const AEDesc *container, long* result)
  146. {   
  147.     AEDesc      aDesc = {typeNull, NULL},
  148.                 tempDesc = {typeNull, NULL};
  149.     TextToken   aTextToken;
  150.     MenuToken   aMenuToken;
  151.     Size        actualSize;
  152.     short        shortResult;
  153.     OSErr       err;
  154.         
  155.             // If it's an object specifier, resolve into a token
  156.     if (typeObjectSpecifier == container->descriptorType)
  157.         err = AEResolve(container, kAEIDoMinimum, &tempDesc);
  158.     else    // Otherwise, just copy it
  159.         err = AEDuplicateDesc(container, &tempDesc);
  160.         
  161.     if (noErr != err) goto done;
  162.     
  163.     *result = -1;            // easily recognized illegal value
  164.     
  165.     switch (desiredType)
  166.     {
  167.         case cWindow:
  168.             if ((containerClass == typeNull) || (containerClass == cApplication))
  169.                 *result = CountWindows();
  170.             else
  171.                 err = errAEWrongDataType;
  172.             break;
  173.  
  174.         case cDocument:
  175.             if ((containerClass == typeNull) || (containerClass == cApplication))
  176.                 *result = CountDocuments();
  177.             else
  178.                 err = errAEWrongDataType;
  179.             break;
  180.             
  181.         case cChar:
  182.         case cWord:
  183.         case cParagraph:
  184.             err = AECoerceDesc(&tempDesc, typeMyText, &aDesc);
  185.             if (typeNull == aDesc.descriptorType)
  186.                 err = errAENoSuchObject;
  187.             if (noErr != err) break;
  188.             GetRawDataFromDescriptor(&aDesc, (Ptr)&aTextToken, sizeof(aTextToken), &actualSize);
  189.  
  190.             err = CountTextElements(TEHandleFromTextToken(&aTextToken),
  191.                                         aTextToken.tokenOffset, aTextToken.tokenLength,
  192.                                                                     desiredType, &shortResult);
  193.             if (noErr != err) break;
  194.             *result = shortResult;
  195.             break;
  196.             
  197.         case cMenu:
  198.             if ((containerClass == typeNull) || (containerClass == cApplication))
  199.                 *result = CountMenus( );
  200.             else
  201.                 err = errAEWrongDataType;
  202.             break;
  203.             
  204.         case cMenuItem:
  205.             if ( typeMyMenu == tempDesc.descriptorType )
  206.             {
  207.                 GetRawDataFromDescriptor( &tempDesc,
  208.                         (Ptr)&aMenuToken, sizeof( aMenuToken ), &actualSize );
  209.  
  210.                 *result = CountMenuTokenItems( &aMenuToken );
  211.             }
  212.             else
  213.                 err = errAEWrongDataType;
  214.             break;
  215.             
  216.         default:
  217.             err = errAECantHandleClass;
  218.     }
  219.     
  220. done:
  221.     if (tempDesc.dataHandle)
  222.         AEDisposeDesc(&tempDesc);
  223.     if (aDesc.dataHandle)
  224.         AEDisposeDesc(&aDesc);
  225.         
  226.     return(err);
  227. }    // MyCountProc
  228.